package com.example.routelink.gateway.filter;

import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.example.routelink.gateway.entity.ResultEnum;
import com.example.routelink.gateway.forest.CommonClient;
import com.example.routelink.gateway.utils.IpUtils;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Map;

@Component
@Slf4j
public class IpHomeLocationGatewayFilterFactory extends BaseFilter<IpHomeLocationGatewayFilterFactory.Config> implements Ordered {
    public IpHomeLocationGatewayFilterFactory() {
        super(IpHomeLocationGatewayFilterFactory.Config.class);
    }

    @Resource
    CommonClient commonClient;

    private final String filterName = "IP归属地";

    @Override
    public GatewayFilter apply(IpHomeLocationGatewayFilterFactory.Config config) {
        return (exchange, chain) -> {
            long startTime = System.currentTimeMillis();
            String gatewayCustomIpLocation = "gatewayCustomIpLocation";
            String ip = IpUtils.getRealIpAddress(exchange.getRequest());

//            ip = "220.181.108.91";  // test
            Map<String, String> originalMap = exchange.getRequest().getQueryParams().toSingleValueMap();
            if (Ipv4Util.isInnerIP(ip)) {
                originalMap.put(gatewayCustomIpLocation, "局内网");
            } else {
                String str = commonClient.getIpLocation(ip);
                JSONObject json = JSON.parseObject(str);
                Object location = json.getByPath("$.data.location[0]");
                if (StrUtil.isEmpty(location.toString())) {
                    return this.response(exchange, ResultEnum.ErrIpLocation);
                }
                originalMap.put(gatewayCustomIpLocation, location.toString());
            }

            String newUrl = exchange.getRequest().getURI().toString().split("\\?")[0];
            newUrl = newUrl + "?" + URLUtil.buildQuery(originalMap, StandardCharsets.UTF_8);
            ServerHttpRequest request = exchange.getRequest().mutate().uri(URLUtil.toURI(newUrl))
                    .build();
            ServerWebExchange mutatedExchange = exchange.mutate().request(request).build();
            writeLog(filterName, startTime, "识别成功,归属地 {} ", originalMap.get(gatewayCustomIpLocation));
            return chain.filter(mutatedExchange);
        };
    }


    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }

    @Data
    public static class Config {

    }
}
